<?php
include_once 'application/controllers/AbstractController.php';
require_once 'application/models/Exercice.php';
require_once 'application/models/Batterie.php';

class ExerciceController extends AbstractController 
{
    //TODO: liste des exercices de la série ?
	function indexAction()
    {
		parent::indexAction();
    	HttpUtil::do405();
    }
    
    
    function getAction()
    {
		parent::getAction();
    	HttpUtil::do405();
    }
    
    
    
    function postAction()
    {
		parent::postAction();
		$batId = $this->getRequest()->getParam('batterie_id');

		// check rights
		$tableB = new Batterie();
		$wherePublicReading = $tableB->getAdapter()->quoteInto('(visibility_id < ?)', Batterie::$_VISIBILITY_PRIVATE);
		$whereOwner = $tableB->getAdapter()->quoteInto('(owner_id = ?)', $this->user->id);
	    $where = $tableB->getAdapter()->quoteInto('id = ?', $batId);
	    $batterieRows = $tableB->fetchAll(array($where, $wherePublicReading.' OR '.$whereOwner));
	    if (!isset($batterieRows[0])) {
	    	HttpUtil::do400('not_owner');
	    }
	
	    // insert
		if (isset($_FILES["csvfile"])){
			// multiple upload
			$this->postCsv($batId);
		}else{
			// single upload
			$this->postSingle($batId);
		}
    }

    private function postCsv($batId) {
		
		// check that this batterie exists
		$table = new Batterie();
		$where = $table->getAdapter()->quoteInto('id = ?', $batId);
	    $batRows = $table->fetchAll($where);
	    if (!isset($batRows[0])) {
	    	// error (not a 400, in order to be read by the iframe)
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceCsvPostFailure("batterie_missed");'.
				'</script>';
			return;
	    }else{
	    	$bat = $table->getArrayFromRow($batRows[0]);
	    }
		
		// Si un CSV est passé
		$csvChecker = CsvUtil::getInstance();
		
		if (!$csvChecker->check($_FILES["csvfile"])) {
	    	// error (not a 400, in order to be read by the iframe)
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceCsvPostFailure("wrong_csv");'.
				'</script>';
			return;
		}
		
		if (!$csvChecker->save($bat)) {
	    	// error (not a 400, in order to be read by the iframe)
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceCsvPostFailure("creation_failed");'.
				'</script>';
			return;
		}
		
		HttpUtil::set201();
		// return data for ajax iframe
		$this->view->data = 
			'<script language="javascript" type="text/javascript">'.
				'window.top.window.exerciceCsvPostSuccess();'.
			'</script>';
    }

    private function postSingle($batId) {
		
		// check that this batterie exists
		$tableB = new Batterie();
		$where = $tableB->getAdapter()->quoteInto('id = ?', $batId);
	    $batRows = $tableB->fetchAll($where);
	    if (!isset($batRows[0])) {
	    	HttpUtil::do401('batterie_missed');
			return;
	    }else{
	    	$bat = $tableB->getArrayFromRow($batRows[0]);
	    }
		
		// get params
		$description = $this->getRequest()->getParam('description');
		$question = $this->getRequest()->getParam('question');
		$reponse_complete = $this->getRequest()->getParam('reponse_complete');
		
		if (!isset($question) || ("" == $question)) {$question = $description;}
		if (!isset($reponse_complete) || ("" == $reponse_complete)) {$reponse_complete = $description;}
		
		$tableE = new Exercice();
		
		// check params type
		$isValid = TypeChecker::validate(array(
			array('data' => $description, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'description'),
			array('data' => $question, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'question'),
			array('data' => $reponse_complete, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'reponse_complete')
		));
		if ($isValid !== true) {
			HttpUtil::do400('validation', $isValid);
		}
		
		//TODO: check injection SQL (ca a l'air good)
		
	    // insert the new batterie
		try {
			$data = array(
			    'batterie_id' => $bat['id'],
			    'type_id' => 2,
				'description' => $description,
				'question' => $question,
				'reponse_complete' => $reponse_complete
			);
			 
			$lastInsertId = $tableE->insert($data);	    
		}catch(Exception $exception) {
			HttpUtil::do400('creation_failed');
		}
	    
		//TODO: prendre en compte 201 (l'helper json annule cet appel)
		HttpUtil::set201();

		// get created batterie
		$tableE = new Exercice();
		$where = $tableE->getAdapter()->quoteInto('id = ?', $lastInsertId);
	    $exRows = $tableE->fetchAll($where);
	    
	    // return the created coloc
	    if (isset($exRows[0])) {
		    $metaData = $tableB->getLastMetaData($batRows[0]);
		    
			$this->view->data = json_encode(array_merge($tableE->getArrayFromRow($exRows[0]), $metaData));
	    }else{
			HttpUtil::do400('getting_failed');
	    }
    }
    
    
    function putAction()
    {
		parent::putAction();
    	//TODO: check rights pour chaque fonction
		//TODO: modification_date (pour le cache surtout -> faire un hash et comparer)
		
		// get params
		$id = $this->getRequest()->getParam('exercice_id');
		$description = $this->getRequest()->getParam('description');
		$question = $this->getRequest()->getParam('question');
		$reponse_complete = $this->getRequest()->getParam('reponse_complete');
		
		// check params type
		$isValid = TypeChecker::validate(array(
			array('data' => $id, 'type' => TypeChecker::$_NUM_TYPE, 'name' => 'id'),
			array('data' => $description, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'description'),
			array('data' => $question, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'question'),
			array('data' => $reponse_complete, 'type' => TypeChecker::$_TEXT_TYPE, 'name' => 'reponse_complete')
		));
		if ($isValid !== true) {
			HttpUtil::do400('validation', $isValid);
		}
   		
		try {
			// get exercice
			$table = new Exercice();
		    $where = $table->getAdapter()->quoteInto('id = ?', $id);
		    $exerciceRows = $table->fetchAll($where);
		    if (!isset($exerciceRows[0])) {
		    	HttpUtil::do404();
		    }
		    $exercice = $table->getArrayFromRow($exerciceRows[0]);
			
			// check rights on batterie
			$tableB = new Batterie();
			$wherePublicReading = $tableB->getAdapter()->quoteInto('(visibility_id < ?)',Batterie::$_VISIBILITY_PRIVATE);
			$whereOwner = $tableB->getAdapter()->quoteInto('(owner_id = ?)', $this->user->id);
		    $where = $tableB->getAdapter()->quoteInto('id = ?', $exercice['batterie_id']);
		    $batterieRows = $tableB->fetchAll(array($where, $wherePublicReading.' OR '.$whereOwner));
		    if (!isset($batterieRows[0])) {
		    	HttpUtil::do400('not_owner');
		    }
			
			// update table
			$table = new Exercice();
			$data = array(
				'description'=> $description,
				'question'=> $question,
				'reponse_complete'=> $reponse_complete
			);
			$where = $table->getAdapter()->quoteInto('id = ?', $id);
			$numberOfRows = $table->update($data, $where);
		}catch(Exception $exception) {
			HttpUtil::do400('update_failed');
		}
		// we do not check the number of rows, 'cause in the case of putting the same
		// data that the existing one : then, numberofrows = 0 (although it's a success)
		
	    //return 200
		$data['id'] = $id;
	    $this->_helper->json($data);
    }
    
    
    
    function deleteAction()
    {
		parent::deleteAction();
		
		try {
			// get params
			$ids = explode ( "," , $this->getRequest()->getParam('ids'));

	    	for ($i = 0; $i < count($ids); $i++) {
	    		$id = $ids[$i];
	    		
				// get exercice
				$table = new Exercice();
			    $where = $table->getAdapter()->quoteInto('id = ?', $id);
			    $exerciceRows = $table->fetchAll($where);
		    
	    		if (!isset($exerciceRows[0])) {
			    	continue;
			    }
			    			    
		    	$exercice = $table->getArrayFromRow($exerciceRows[0]);
		    		
		    	// check rights on batteries
		    	$tableB = new Batterie();
		    	$wherePublicReading = $tableB->getAdapter()->quoteInto('(visibility_id < ?)',Batterie::$_VISIBILITY_PRIVATE);
		    	$whereOwner = $tableB->getAdapter()->quoteInto('(owner_id = ?)', $this->user->id);
		    	$where = $tableB->getAdapter()->quoteInto('id = ?', $exercice['batterie_id']);
		    	$batterieRows = $tableB->fetchAll(array($where, $wherePublicReading.' OR '.$whereOwner));
		    	if (!isset($batterieRows[0])) {
		    		HttpUtil::do400('not_owner');
		    	}
		    		
		    	// delete
		    	$tableE = new Exercice();
		    	$where = $tableE->getAdapter()->quoteInto('id = ?', $id);
		    	$numberOfRows = $tableE->delete($where);
		    }

		}catch(Exception $exception) {
			//TODO: rollback !!!
			HttpUtil::do400('delete_failed');
		}
	    
	    // check the number of rows deleted
	    if ($numberOfRows < 1) {
			HttpUtil::do404();
	    }
    }
    
    
    function imageAction()
    {
		$s = Zend_Registry::getInstance()->get('config')->directory->fileseparator;
    	if (!isset($_FILES["imagefile"])) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceImagePostFailure("file_missed");'.
				'</script>';
			return;
		}
		
		$id = $this->getRequest()->getParam('exercice_id');
		$rowId = $this->getRequest()->getParam('row_id');

		// Get exercice
	    $exercice = new Exercice();
		$where = $exercice->getAdapter()->quoteInto('id = ?', $id);
	    $exerciceRows = $exercice->fetchAll($where);
		
		if (!isset($exerciceRows[0])) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceImagePostFailure("exercice_missed");'.
				'</script>';
			return;
		}
		$exercice = $exerciceRows[0];
		
		// check if image and size (IsImage doesn't work fine on Wamp)
		$upload = new Zend_File_Transfer();
		$upload->addValidator('ImageSize',
                      false,
                      array('minwidth' => 0,
                            'maxwidth' => 800,
                            'minheight' => 0,
                            'maxheight' => 500))
				->addValidator('FilesSize', false, array('max' => '1MB'));		
	    if (!$upload->isValid("imagefile")) {
    		$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceImagePostFailure("wrong_image");'.
				'</script>';
			return;
		}
		
		
		// save image
		$workDir = Zend_Registry::getInstance()->get('config')->directory->work;
		$finalDir = 
			$workDir.
			$s.'batteries'.
			$s.$exercice->batterie_id.
			$s.$exercice->id;
		if (!file_exists($finalDir)) {
			mkdir($finalDir, 0777, true);
		}
		$imageName = FileUtil::stripAccents($_FILES["imagefile"]['name']);
		
		// remove older file if needed (before saving the other in case of similar names)
		if ($exercice->has_image){
			$resultat = unlink($finalDir.$s.$exercice->image_name);
		}

		// save new file
		$resultat = move_uploaded_file($_FILES["imagefile"]['tmp_name'], $finalDir.$s.$imageName);
		if (!$resultat) {
    		$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceImagePostFailure("upload_failed");'.
				'</script>';
			return;
		}
		
		// save name in DB
		try {
			$table = new Exercice();
			 
			$data = array(
				'has_image'=> true,
				'image_name'=> $imageName
			);
			 
			$where = $table->getAdapter()->quoteInto('id = ?', $id);

			$numberOfRows = $table->update($data, $where);

		}catch(Exception $exception) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceImagePostFailure("update_failed");'.
				'</script>';
			return;
		}
		
		$externalPath = 
			'p'.
			'/'.'batteries'.
			'/'.$exercice->batterie_id.
			'/'.$exercice->id.
			'/'.$imageName;
		
		$this->view->data = 
			'<script language="javascript" type="text/javascript">'.
				'window.top.window.exerciceImagePostSuccess("'. $rowId .'", "'. $externalPath .'");'.
			'</script>';
    }
    
    function removeimageAction()
    {
		$s = Zend_Registry::getInstance()->get('config')->directory->fileseparator;
    	$id = $this->getRequest()->getParam('exercice_id');

		//TODO: check right on this ex (global function ?)
		
		// check params type
		$isValid = TypeChecker::validate(array(
			array('data' => $id, 'type' => TypeChecker::$_NUM_TYPE, 'name' => 'exercice_id')
		));
		if ($isValid !== true) {
			HttpUtil::do400('validation', $isValid);
		}
		
		// Get exercice
	    $exercice = new Exercice();
		$where = $exercice->getAdapter()->quoteInto('id = ?', $id);
	    $exerciceRows = $exercice->fetchAll($where);
		
		if (!isset($exerciceRows[0])) {
			HttpUtil::do404('exercice_missed');
		}
		$exercice = $exerciceRows[0];
		
		// remove file if needed
		if ($exercice->has_image){
			$workDir = Zend_Registry::getInstance()->get('config')->directory->work;
			$finalDir = 
				$workDir.
				$s.'batteries'.
				$s.$exercice->batterie_id.
				$s.$exercice->id;
			if (file_exists($finalDir.$s.$exercice->image_name)) {
				unlink($finalDir.$s.$exercice->image_name);
			}
		}
		
		try {
			$table = new Exercice();
			 
			$data = array(
				'has_image'=> '0',
				'image_name'=> null
			);
			 
			$where = $table->getAdapter()->quoteInto('id = ?', $id);

			$numberOfRows = $table->update($data, $where);

		}catch(Exception $exception) {
			print_r($exception);exit;
			HttpUtil::do400('update_failed');
		}
		
	    // check the number of rows updated
	    if ($numberOfRows < 1) {
			HttpUtil::do404('exercice_missed');
		}
    }
    
    function audioAction()
    {
		$s = Zend_Registry::getInstance()->get('config')->directory->fileseparator;
    	if (!isset($_FILES["audiofile"])) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceAudioPostFailure("file_missed");'.
				'</script>';
			return;
		}
		
		$id = $this->getRequest()->getParam('exercice_id');
		$rowId = $this->getRequest()->getParam('row_id');

		// Get exercice
	    $exercice = new Exercice();
		$where = $exercice->getAdapter()->quoteInto('id = ?', $id);
	    $exerciceRows = $exercice->fetchAll($where);
		
		if (!isset($exerciceRows[0])) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceAudioPostFailure("exercice_missed");'.
				'</script>';
			return;
		}
		$exercice = $exerciceRows[0];
		
		// check if sound
		$upload = new Zend_File_Transfer();
		$upload ->addValidator('FilesSize', false, array('max' => '1MB'))		
				->addValidator('Extension', false, array('mp3'));
				
	    if (!$upload->isValid("audiofile")) {
    		$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceAudioPostFailure("wrong_sound");'.
				'</script>';
			return;
		}
		
		// save sound
		$workDir = Zend_Registry::getInstance()->get('config')->directory->work;
		$finalDir = 
			$workDir.
			$s.'batteries'.
			$s.$exercice->batterie_id.
			$s.$exercice->id;
		if (!file_exists($finalDir)) {
			mkdir($finalDir, 0777, true);
		}
		$soundName = FileUtil::stripAccents($_FILES["audiofile"]['name']);
		
		// remove older file if needed (before saving the other in case of similar names)
		if ($exercice->has_sound){
			$resultat = unlink($finalDir.$s.$exercice->sound_name);
		}

		// save new file
		$resultat = move_uploaded_file($_FILES["audiofile"]['tmp_name'], $finalDir.$s.$soundName);
		if (!$resultat) {
    		$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceAudioPostFailure("upload_failed");'.
				'</script>';
			return;
		}
		
		// save name in DB
		try {
			$table = new Exercice();
			 
			$data = array(
				'has_sound'=> true,
				'sound_name'=> $soundName
			);
			 
			$where = $table->getAdapter()->quoteInto('id = ?', $id);

			$numberOfRows = $table->update($data, $where);

		}catch(Exception $exception) {
			$this->view->data = 
				'<script language="javascript" type="text/javascript">'.
					'window.top.window.exerciceAudioPostFailure("update_failed");'.
				'</script>';
			return;
		}
		
		$externalPath = 
			'p'.
			'/'.'batteries'.
			'/'.$exercice->batterie_id.
			'/'.$exercice->id.
			'/'.$soundName;
		
		$this->view->data = 
			'<script language="javascript" type="text/javascript">'.
				'window.top.window.exerciceAudioPostSuccess("'. $rowId .'", "'. $externalPath .'");'.
			'</script>';
    }
   
    function removeaudioAction()
    {
		$s = Zend_Registry::getInstance()->get('config')->directory->fileseparator;
    	$id = $this->getRequest()->getParam('exercice_id');

		//TODO: check right on this ex (global function ?)
		
		// check params type
		$isValid = TypeChecker::validate(array(
			array('data' => $id, 'type' => TypeChecker::$_NUM_TYPE, 'name' => 'exercice_id')
		));
		if ($isValid !== true) {
			HttpUtil::do400('validation', $isValid);
		}
		
		// Get exercice
	    $exercice = new Exercice();
		$where = $exercice->getAdapter()->quoteInto('id = ?', $id);
	    $exerciceRows = $exercice->fetchAll($where);
		
		if (!isset($exerciceRows[0])) {
			HttpUtil::do404('exercice_missed');
		}
		$exercice = $exerciceRows[0];
		
		// remove file if needed
		if ($exercice->has_sound){
			$workDir = Zend_Registry::getInstance()->get('config')->directory->work;
			$finalDir = 
				$workDir.
				$s.'batteries'.
				$s.$exercice->batterie_id.
				$s.$exercice->id;
			if (file_exists($finalDir.$s.$exercice->sound_name)) {
				unlink($finalDir.$s.$exercice->sound_name);
			}
		}
		
		try {
			$table = new Exercice();
			 
			$data = array(
				'has_sound'=> '0',
				'sound_name'=> null
			);
			 
			$where = $table->getAdapter()->quoteInto('id = ?', $id);

			$numberOfRows = $table->update($data, $where);

		}catch(Exception $exception) {
			print_r($exception);exit;
			HttpUtil::do400('update_failed');
		}
		
	    // check the number of rows updated
	    if ($numberOfRows < 1) {
			HttpUtil::do404('exercice_missed');
		}
    }
}
